
#include <stdio.h>
#include "wm_hal.h"

void Error_Handler(void);

static uint8_t in[1024], out1[1024], out2[1024], key[16], iv[16];

static void rc4_demo(void);
static void aes_demo(void);
static void des_demo(void);
static void des3_demo(void);
static void crc_demo(void);

int main(void)
{
	SystemClock_Config(CPU_CLK_160M);
	printf("enter main\r\n");
	rc4_demo();
	aes_demo();
	des_demo();
	des3_demo();
	crc_demo();
	
	while (1)
	{
		printf(".");
		HAL_Delay(1000);
	}
}

static void rc4_demo(void)
{
	psCipherContext_t ctx;
	
	HAL_CRYPTO_TRNG(in, 1000);
	HAL_CRYPTO_TRNG(key, 16);
	
	HAL_CRYPTO_RC4_Init(&ctx, key, 16);
	HAL_CRYPTO_RC4(&ctx, in, out1, 1000);
	HAL_CRYPTO_RC4(&ctx, out1, out2, 1000);
	if (memcmp(in, out2, 1000) != 0)
	{
		printf("rc4 test failed\r\n");
	}
	else
	{
		printf("rc4 test success\r\n");
	}
}

static void aes_demo(void)
{
	psCipherContext_t ctx;
	
	HAL_CRYPTO_TRNG(in, 1024);
	HAL_CRYPTO_TRNG(key, 16);
	HAL_CRYPTO_TRNG(iv, 16);
	
	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	HAL_CRYPTO_AES_Init(&ctx, iv, key, 16, CRYPTO_MODE_ECB);
	HAL_CRYPTO_AES_Encrypt_Decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	HAL_CRYPTO_AES_Encrypt_Decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if (memcmp(in, out2, 1024) != 0)
	{
		printf("aes ecb test failed\r\n");
	}
	else
	{
		printf("aes ecb test success\r\n");
	}
	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	HAL_CRYPTO_AES_Init(&ctx, iv, key, 16, CRYPTO_MODE_CBC);
	HAL_CRYPTO_AES_Encrypt_Decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	HAL_CRYPTO_AES_Encrypt_Decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if (memcmp(in, out2, 1024) != 0)
	{
		printf("aes cbc test failed\r\n");
	}
	else
	{
		printf("aes cbc test success\r\n");
	}
	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	HAL_CRYPTO_AES_Init(&ctx, iv, key, 16, CRYPTO_MODE_CTR);
	HAL_CRYPTO_AES_Encrypt_Decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	HAL_CRYPTO_AES_Encrypt_Decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if (memcmp(in, out2, 1024) != 0)
	{
		printf("aes ctr test failed\r\n");
	}
	else
	{
		printf("aes ctr test success\r\n");
	}
}

static void des_demo(void)
{
	psCipherContext_t ctx;
	
	HAL_CRYPTO_TRNG(in, 1024);
	HAL_CRYPTO_TRNG(key, 8);
	HAL_CRYPTO_TRNG(iv, 8);
	
	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	HAL_CRYPTO_DES_Init(&ctx, iv, key, 8, CRYPTO_MODE_ECB);
	HAL_CRYPTO_DES_Encrypt_Decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	HAL_CRYPTO_DES_Encrypt_Decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if (memcmp(in, out2, 1024) != 0)
	{
		printf("des ecb test failed\r\n");
	}
	else
	{
		printf("des ecb test success\r\n");
	}
	
	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	HAL_CRYPTO_DES_Init(&ctx, iv, key, 8, CRYPTO_MODE_CBC);
	HAL_CRYPTO_DES_Encrypt_Decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	HAL_CRYPTO_DES_Encrypt_Decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if (memcmp(in, out2, 1024) != 0)
	{
		printf("des cbc test failed\r\n");
	}
	else
	{
		printf("des cbc test success\r\n");
	}
}

static void des3_demo(void)
{
	psCipherContext_t ctx;
	
	HAL_CRYPTO_TRNG(in, 1024);
	HAL_CRYPTO_TRNG(key, 24);
	HAL_CRYPTO_TRNG(iv, 8);
	
	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	HAL_CRYPTO_3DES_Init(&ctx, iv, key, 24, CRYPTO_MODE_ECB);
	HAL_CRYPTO_3DES_Encrypt_Decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	HAL_CRYPTO_3DES_Encrypt_Decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if (memcmp(in, out2, 1024) != 0)
	{
		printf("3des ecb test failed\r\n");
	}
	else
	{
		printf("3des ecb test success\r\n");
	}
	
	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	HAL_CRYPTO_3DES_Init(&ctx, iv, key, 24, CRYPTO_MODE_CBC);
	HAL_CRYPTO_3DES_Encrypt_Decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	HAL_CRYPTO_3DES_Encrypt_Decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if (memcmp(in, out2, 1024) != 0)
	{
		printf("3des cbc test failed\r\n");
	}
	else
	{
		printf("3des cbc test success\r\n");
	}
}

static void crc_demo(void)
{
	uint32_t crckey = 0xFFFFFFFF;
	CRC_HandleTypeDef ctx;
	uint32_t crcvalue = 0;
	
	HAL_CRYPTO_TRNG(in, 1024);
	
	HAL_CRYPTO_CRC_Init(&ctx, crckey, CRYPTO_CRC_TYPE_32, (OUTPUT_REFLECT | INPUT_REFLECT));
	HAL_CRYPTO_CRC_Update(&ctx, in, 1024);
	HAL_CRYPTO_CRC_Update(&ctx, in, 1024);
	HAL_CRYPTO_CRC_Update(&ctx, in, 1024);
	HAL_CRYPTO_CRC_Final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_32 INPUT_REFLECT | OUTPUT_REFLECT value:0x%08X\n", crcvalue);
	
}

void Error_Handler(void)
{
	while (1)
	{
	}
}

void assert_failed(uint8_t *file, uint32_t line)
{
	printf("Wrong parameters value: file %s on line %d\r\n", file, line);
}